package fun.boomcat.luckyhe.mirai.plugin.luckymoney.service.impl;

import fun.boomcat.luckyhe.mirai.plugin.luckymoney.entity.UserMoney;
import fun.boomcat.luckyhe.mirai.plugin.luckymoney.exception.MoneyNotEnoughException;
import fun.boomcat.luckyhe.mirai.plugin.luckymoney.mapper.MoneyMapper;
import fun.boomcat.luckyhe.mirai.plugin.luckymoney.service.MoneyService;
import fun.boomcat.luckyhe.mirai.plugin.luckymoney.util.MyBatisUtil;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.SqlSession;

import java.io.IOException;

/**
 * @author Lucky_He
 * @date 2021年9月5日 14:58
 * @description MoneyServiceImpl
 */
public class MoneyServiceImpl implements MoneyService {

    @Override
    public int createMoneyDB() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);
        int res = mapper.createMoneyDB();
        sqlSession.close();
        return res;
    }

    @Override
    public int createMoneyTable() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);
        int res = mapper.createMoneyTable();
        sqlSession.close();
        return res;
    }

    @Override
    public UserMoney selectUserMoneyByQq(long qq) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);
        UserMoney userMoney = mapper.selectUserMoneyByQq(qq);

        sqlSession.close();

        return userMoney;
    }

    @Override
    public UserMoney getUserMoneyByQq(long qq) throws IOException {
//        该方法如果得不到则会自动创建
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        UserMoney userMoney = mapper.selectUserMoneyByQq(qq);
        if (userMoney == null) {
            System.out.println("usermoney is null!");
            mapper.insertUserMoney(new UserMoney(null, qq, 0));
            userMoney = mapper.selectUserMoneyByQq(qq);
        }
        sqlSession.commit();
        sqlSession.close();
        return userMoney;
    }

    @Override
    public int insertUserMoney(UserMoney userMoney) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);
        int res = mapper.insertUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int addUserMoney(UserMoney userMoney, int addMoney) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        userMoney.setMoney(userMoney.getMoney() + addMoney);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int addUserMoneyByQq(long qq, int addMoney) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        UserMoney userMoney = mapper.selectUserMoneyByQq(qq);

        if (userMoney == null) {
            mapper.insertUserMoney(new UserMoney(null, qq, 0));
            userMoney = mapper.selectUserMoneyByQq(qq);
        }
        userMoney.setMoney(userMoney.getMoney() + addMoney);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int takeUserMoney(UserMoney userMoney, int delMoney) throws IOException, MoneyNotEnoughException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        int bal = userMoney.getMoney() - delMoney;
        if (bal < 0) {
            throw new MoneyNotEnoughException(userMoney.getMoney(), delMoney);
        }

        userMoney.setMoney(bal);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int takeUserMoneyByQq(long qq, int delMoney) throws IOException, MoneyNotEnoughException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        UserMoney userMoney = mapper.selectUserMoneyByQq(qq);

        if (userMoney == null) {
            mapper.insertUserMoney(new UserMoney(null, qq, 0));
            userMoney = mapper.selectUserMoneyByQq(qq);
        }

        int bal = userMoney.getMoney() - delMoney;
        if (bal < 0) {
            throw new MoneyNotEnoughException(userMoney.getMoney(), delMoney);
        }
        userMoney.setMoney(bal);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int forceTakeUserMoney(UserMoney userMoney, int delMoney) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        userMoney.setMoney(userMoney.getMoney() - delMoney);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public int forceTakeUserMoneyByQq(long qq, int delMoney) throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        UserMoney userMoney = mapper.selectUserMoneyByQq(qq);

        if (userMoney == null) {
            mapper.insertUserMoney(new UserMoney(null, qq, 0));
            userMoney = mapper.selectUserMoneyByQq(qq);
        }

        userMoney.setMoney(userMoney.getMoney() - delMoney);
        int res = mapper.updateUserMoney(userMoney);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    @Override
    public void payUserMoney(UserMoney srcUser, UserMoney destUser, int money) throws IOException, MoneyNotEnoughException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        int bal = srcUser.getMoney() - money;
        if (bal < 0) {
            throw new MoneyNotEnoughException(srcUser.getMoney(), money);
        }

        srcUser.setMoney(bal);
        destUser.setMoney(destUser.getMoney() + money);

        mapper.updateUserMoney(srcUser);
        mapper.updateUserMoney(destUser);

        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void payUserMoneyByQq(long srcQq, long destQq, int money) throws IOException, MoneyNotEnoughException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        MoneyMapper mapper = sqlSession.getMapper(MoneyMapper.class);

        UserMoney srcUser = mapper.selectUserMoneyByQq(srcQq);
        if (srcUser == null) {
            mapper.insertUserMoney(new UserMoney(null, srcQq, 0));
            srcUser = mapper.selectUserMoneyByQq(srcQq);
        }

        UserMoney destUser = mapper.selectUserMoneyByQq(destQq);
        if (destUser == null) {
            mapper.insertUserMoney(new UserMoney(null, destQq, 0));
            destUser = mapper.selectUserMoneyByQq(destQq);
        }

        int bal = srcUser.getMoney() - money;
        if (bal < 0) {
            throw new MoneyNotEnoughException(srcUser.getMoney(), money);
        }

        srcUser.setMoney(bal);
        destUser.setMoney(destUser.getMoney() + money);

        mapper.updateUserMoney(srcUser);
        mapper.updateUserMoney(destUser);

        sqlSession.commit();
        sqlSession.close();
    }
}
